﻿namespace MapleRock.P2PEmulator.RGR
{
  using System;
  using System.Collections.Generic;
  using System.Diagnostics;
  using System.IO;
  using System.Linq;
  using System.Text;

  using MapleRock.P2PEmulator.Core;

  public sealed class ModelOutputFile
  {
    static ModelOutputFile()
    {
      ModelOutputFile.Instance = new ModelOutputFile();
    }

    public static ModelOutputFile Instance { get; private set; }

    private StringBuilder contents = new StringBuilder();

    public void BeginExperiment(
      int samples, 
      int runs, 
      int dimensions, 
      double datagrammLossProb, 
      int maxPeerLinks)
    {
      this.contents.AppendLine("# experiment date " + DateTime.Now);

      this.contents.AppendFormat(
        "{0} {1} {2} {3} {4}", 
        samples, 
        runs, 
        dimensions, 
        datagrammLossProb, 
        maxPeerLinks);
      this.contents.AppendLine();
    }

    public void EndExperiment()
    {
      this.contents.AppendLine();
    }

    public void BeginSample(int pn)
    {
      this.contents.AppendLine("\t# sample");
      this.contents.AppendLine("\t" + pn);
    }

    public void EndSample()
    {
      this.contents.AppendLine();
    }

    public void BeginRun()
    {
      this.contents.AppendLine("\t\t# run");
    }

    public void EndRun()
    {
      this.contents.AppendLine();
    }

    public void PeerState(Peer peer)
    {
      this.contents.AppendLine("\t\t\t# peer");

      this.contents.AppendFormat(
        "\t\t\t{0} {1} {2} {3} {4}", 
        peer.Id,
        peer.TrafficCounter, 
        peer.SearchRequestsSent,
        peer.SearchRequestsSucceded,
        peer.SearchRequestsFailed);
      this.contents.AppendLine();

      if (peer.SearchRequestCompletionPeriods.Count > 0)
      {
        this.contents.Append("\t\t\t");

        foreach (var c in peer.SearchRequestCompletionPeriods)
        {
          this.contents.AppendFormat("{0} ", c);
        }

        this.contents.AppendLine();
      }

      this.contents.Append("\t\t\t");
      foreach (var c in peer.AbsolutePosition)
      {
        this.contents.AppendFormat("{0} ", c);
      }
      this.contents.AppendLine();
    }

    public void Save(string path)
    {
      Debug.Assert(!string.IsNullOrEmpty(path), "!string.IsNullOrEmpty(path)");
      File.WriteAllText(path, contents.ToString());
    }
  }
}
